package org.jrfe.net.simple;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;

import org.jrfe.net.NetPackege;
import org.jrfe.net.SyncQueue;

public class SServer implements Runnable {

	protected int port;

	protected NetworkCallback callback;

	protected boolean running;
	protected Thread thread;

	protected ServerSocket serverSocket;
	protected Socket clientSocket;

	protected ObjectInputStream ois;
	protected ObjectOutputStream oos;

	protected SyncQueue<NetPackege> queue;
 
	protected boolean ready;

	public SServer(int port, NetworkCallback callback) throws IOException {
		this.port = port;
		this.callback = callback;
		queue = new SyncQueue<NetPackege>();
		serverSocket = new ServerSocket(port);

		ready = false;

	}

	public Thread getThread() {
		return thread;
	}
	
	public void start() {
		thread = new Thread(this);
		running = true;
		thread.start();
	}

	public void stop() {
		running = false;

		try {
			ois.close();
			oos.close();
			serverSocket.close();
			
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public SyncQueue<NetPackege> getQueue() {
		return queue;
	}

	public synchronized boolean send(NetPackege pkg) {
			if (ready) {
				try {
					oos.writeObject(pkg);
					oos.flush();
				} catch (Exception e) {
					// callback sending error (connection was lost or dmething like that)
					e.printStackTrace();
				}
				return true;
			}
			return false;
	}

	@Override
	public void run() {

		while (running) {
			if (!ready) {
				try {
					System.out.println("Waiting for connection...");
					clientSocket = serverSocket.accept();
					ois = new ObjectInputStream(clientSocket.getInputStream());
					oos = new ObjectOutputStream(clientSocket.getOutputStream());
					System.out.println("Connected!!!");
					callback.connected();
					ready = true;
				} catch (Exception e) {
					// if this oocures is Bad very Bad
					// callback cant accept coonections (need reboot or something)
					callback.connectionError();
					e.printStackTrace();
				}
			} else {
				try {
					Object ob = ois.readObject();
					if (ob != null) {
						queue.writeQueue((NetPackege) ob);
					}
				} catch (Exception e) {
					callback.connectionLost();
					// Callback error (dowitn reconnection)
					System.out.println("Connection closed!!!");
					//e.printStackTrace();
					ready = false;
				}
			}
		}

	}

	public static void main(String[] args) throws Exception {
		SServer s = new SServer(1234, null);
		s.start();

		Thread.sleep(1000);

		s.stop();
	}

}
